#include"Diary.h"
#include <iomanip>

Diary* Diary:: diaryPtr = 0; // init static data 
const string Diary::participators[10] = {"A","B","C","D","E","F","G","H","I","J"};
const string Diary::weekDays[7] = { "Sunday", "Monday",
                                     "Tuesday", "Wednesday",
                                     "Thursday", "Friday", "Saturday"};

// default CTOR
Diary::Diary()
{
  for(int i=0;i<7;i++)
  {
	  vectorOfDays.push_back(new Day(weekDays[i]));
  }
}

// add meeting to diary(return 1 if succeeded)
int Diary::addMeetingToDiary(const string& what,const vector<string>& prtcp,const string& sbj,const string& day,int sH,int sM,int eH,int eM)
{
	int temp = 1;

	if(!checkPrt(prtcp))
	{
		temp = 0;
	}
	if(!checkDay(day))
	{
		temp = 0;
	}
	if(!checkTime(sH,sM,eH,eM))
	{
		temp = 0;
	}

	if(temp == 1)
	{
		Meeting* meet = MeetingFactory::CreateMeeting(what,prtcp,sbj,day,sH,sM,eH,eM);
		int i = findNumberOfDay(day);

		if (!((*vectorOfDays[i-1]).checkIntersaction(meet)))
		{
			cout << "Impossible to add meeting (time intersaction)." << endl;
			delete meet;
			return 0;
		}
		else 
		{
			(*vectorOfDays[i-1]).addMeetingToDay(meet);
			return 1;
		}
	}

	return 0;
}
	



//delete meeting from diary
void Diary::deleteMeetingFromDiary(Meeting* meet)
{
	string day = (*meet).getWeekDay(); 
	int i = findNumberOfDay(day);
	(*vectorOfDays[i-1]).deleteMeetingFromDay((*meet).getStartHour(),(*meet).getStartMinute());	
}

//find meeting in the diary in specific day that start in specific time 
Meeting* Diary::findMeetingInDiary(const string& weekDay , int startHour, int startMinute)const
{ 
	int i = findNumberOfDay(weekDay);
	int j = (*vectorOfDays[i-1]).findMeetingInDay(startHour,startMinute);
	if(j == -1)
	{
		return NULL;
	}
	else
	{
		return (*vectorOfDays[i-1]).getVec()[j];	
	}
}

//change time of meeting
void Diary::changeMeetingTime(Meeting* meet,const string& weekDay ,int newstartHour, int newstartMinute, int newendHour, int newendMinute)
{
	if(meet == 0)
	{
		cout << "Can't change meeting that do not exist" <<endl;
		return;
	}
	int i = findNumberOfDay((*meet).getWeekDay());

	if((!checkDay(weekDay)) ||
	   (!checkTime(newstartHour,newstartMinute,newendHour,newendMinute)))
	{
		(*vectorOfDays[i-1]).addMeetingToDay(meet);        //return old meeting  	
	}
	
	int oldSH = (*meet).getStartHour(); 
	int oldSM = (*meet).getStartMinute();
	int oldEH = (*meet).getEndHour();
	int oldEM = (*meet).getEndMinute();

	(*meet).setStartHour(newstartHour);
	(*meet).setStartMinute(newstartMinute);
	(*meet).setEndHour(newendHour);
	(*meet).setEndMinute(newendMinute);

	int j = findNumberOfDay(weekDay);

	//removing meeting from diary for Intersection check
	(*vectorOfDays[i-1]).removeMeetingFromDay((*meet).getStartHour(), (*meet).getStartMinute()); 
	                                              

	if(!((*vectorOfDays[j-1]).checkIntersaction(meet)))
	{
		(*meet).setStartHour(oldSH);
		(*meet).setStartMinute(oldSM);
		(*meet).setEndHour(oldEH);
		(*meet).setEndMinute(oldEM);

		(*vectorOfDays[i-1]).addMeetingToDay(meet);        //return old meeting
	}
	else
	{
		(*meet).setDay(weekDay);
		(*vectorOfDays[j-1]).addMeetingToDay(meet);        //add meeting with new time 
	}

}

// print out Diary data
void Diary::printOut()const
{
	for(int i = 0;i < 5;i++)
	{
		(*vectorOfDays[i]).printOut();
		cout<<endl<<endl;

	}


}	
//chek if vector of participators is correct - all from list and no two with same name
bool Diary::checkPrt(const vector<string>& prtcp)const
{
	int temp1 = 1;
	int temp2 = 0;
	int temp3 = 0;

	for(int k = 0;k<(int)prtcp.size();k++)
	{
		for(int l = k+1;l<(int)prtcp.size();l++)
		{
			if(!(prtcp[k].compare(prtcp[l])))
			{
			    cout << "Name: " <<prtcp[k]<<" and "<<prtcp[l]<<" are the same (illegal)"  <<endl;
				temp1 = 0;
			}
		}
	}
	for(int i=0;i<(int)prtcp.size();i++)
	{
		for(int j=0;j<10;j++)
		{
			if(!((prtcp[i].compare(participators[j]))))
			{
				temp2 = 1;
				break;
			}
		}
		if(temp2 == 0)
		{
			cout << "Name: " <<prtcp[i]<<" is illegal"<< endl;
			temp3 = 1;
		}
		temp2 = 0;
	}
	if((temp1 == 0)||(temp3 == 1))
	{
		return false;
	}
	else
	{
		return true;
	}
}

//check if the day is correct - not Friday or Saturday
bool Diary::checkDay(const string& day)const
{
	if(!(day.compare("Sunday")) || !(day.compare("Monday")) ||!(day.compare("Tuesday")) ||
		!(day.compare("Wednesday")) ||!(day.compare("Thursday")))
	{
		return true;
	}
	else
	{
		cout << "Day: " << day <<" is illegal"<< endl;
		return false;
	}
}

//check if time is correct - start before end , end in the same day it's start, Hour<24, Minute<60
bool Diary::checkTime(int sH,int sM,int eH,int eM)const
{
	int temp = 1;

	if(sH>23||sH<0)
	{
			cout << "Start Hour " << sH << " is illegal " << endl;;
			temp = 0;
	}
	if(sM>59||sM<0)
	{
			cout << "Start Minute " << sM << " is illegal " << endl;;
			temp = 0;
	}
	if(eH>23||eH<0)
	{
			cout << "End hour " << eH << " is illegal " << endl;;
			temp = 0;
	}
	if(eM>59||eM<0)
	{
			cout << "End Minute " << eM << " is illegal " << endl;;
			temp = 0;
	}
	if (temp == 1)
	{
		if((sH*60+sM)>(eH*60+eM))
		{
				cout << setfill('0');
				cout << "Start time " << setw(2) << sH << ":" << setw(2) << sM ;
				cout << " is after end time ";
				cout << setw(2) << eH << ":" << setw(2) << eM << " (illegal) " << endl;
				temp = 0;
		}
	}
	if (temp == 1)
	{
		return true;
	}
	else
	{
		return false;
	}
}



//get string day return the day number 
int Diary::findNumberOfDay(const string& day)const
{
	int temp = 0;
	if(!day.compare("Sunday"))
	{
		temp = 1;
		return temp;
	}
	if(!day.compare("Monday"))
	{
		temp = 2;
		return temp;
	}
	if(!day.compare("Tuesday"))
	{
		temp = 3;
		return temp;
	}
	if(!day.compare("Wednesday"))
	{
		temp = 4;
		return temp;
	}
	if(!day.compare("Thursday"))
	{
		temp = 5;
		return temp;
	}
	if(!day.compare("Friday"))
	{
		temp = 6;
		return temp;
	}
	if(!day.compare("Saturday"))
	{
		temp = 7;
		return temp;
	}
	return temp;
}

//find which day is the larger and return is size
int Diary::findMaxVec()const
{
	int i = ((*vectorOfDays[0]).getVec()).size();
	int j = ((*vectorOfDays[1]).getVec()).size();
	int k = ((*vectorOfDays[2]).getVec()).size();
	int l = ((*vectorOfDays[3]).getVec()).size();
	int h = ((*vectorOfDays[4]).getVec()).size();
	int q = max(i,j);
	int w = max(k,l);
	int e = max(q,w);
	return max(e,h);
}

//getter for vector of days
const vector<Day*>& Diary::getVec()const
{
	return vectorOfDays;
}


// DTOR
Diary::~Diary()
{
	vector<Day*>::iterator it;
    for (it=vectorOfDays.begin() ; it < vectorOfDays.end(); it++)
	{
		(**it).deleteAll();
		delete (*it);
	}
}
